package Model;

import Model.Construction.Batiment;
import Model.Construction.Commerces.Commerce;
import Model.Construction.Industrie.Industrie;
import Model.Construction.Infrastructure;
import Model.Construction.Services.Route;
import Model.Construction.Travailleur;
import java.awt.event.ActionEvent;
import java.awt.event.ActionListener;
import javax.swing.Timer;
import java.util.concurrent.Semaphore;
import java.util.Vector;
import root.Maadjo;

/**
 * La classe ville contient la plupart des structures essentiels au jeu,
 * elle stocke ainsi des tableaux de structure facilitant la recherche et
 * l'utilisation de fonction tel que impot ou la repartition des travailleurs.
 * @author MAADJO
 */
public class Ville {

    private Maadjo maad;
    private int argent;
    private int securite;
    private int attractivite;
    private int travailleur;
    private Board board;
    private final int incomePopulation = 30;
    private int population;
    private int populationActuelle;
    private Vector<Infrastructure> vecteurInfra;
    private Batiment batimentImpot[];
    private Travailleur travailleurList[];
    private Commerce commerceList[];
    private Industrie industrieList[];
    private final Semaphore available = new Semaphore(1, true);
    private boolean hotelVilleConstruit = false;
    private final int limitePopSansHotel = 150;
    private long tempsDebut;
    private long tempsFin;
    private int nourritureConsomme;
    private int textileConsomme;
    private int MaxConsommation;
    private Timer time;
    private String industrie_1;
    private String industrie_2;
    private String industrie_3;
    private String industrie_4;

//                         `-/.````
//                         ..```      ```.`
//                       `..              ``.``
//                      -`                    `..
//                   ``.:                       ..`
//              ````.`.-/-.........`              ..`
//             ..```.:+.-`./:..``...-.              ..
//           .:---....````.+:::``````.--`````       .`
//         `.-..`````````````.````````.-:`  `-..`  .-
//       `--.`````````````````````````.:.       `-..`
//      --```````````````````````````...:.        .-
//     --````````````````````````````....:         .-`  `
//    --````````````````````````````.....:.         :.-..--..-.
//   `:````````````````````````````......-:         -.        ..--```
//   .-`````` ````````````````````.......:.         `:           ````-.
//   --`````` ``  ```````````````.......-:          -`                `--
//   `:`````````````````````````........:`          :                   --`
//    :.```````````````````````........--          `-                     :.
//     :.````````````````````..........:.          ..                     `-.
//      --`````````````````............:.        `-`                       `:`
//       .-.````````````.............-:-        `-`                     ````.:
//         .--..``................---..-        -`                     `````--
//           `.-----.........-----.`   `........`                      `````.:
//              .:`..-------..``                                      ```````:`
//              `/                                                 ``````````:.
//              --                                             `````````````:.
//               -:                                        `````````````````:.
//               .:`              ` ``    `````    ```````````````````````.-.
//                `:.`````````````````````````````````````````````````````/
//                  --.````````````````````````````````````````````````.--.
//                   `.-...`````````````````````````````````````````.-.-`
//                      ``/:.--...`..```...````````...```...``--..-..
//                        /sss. `-ooo/...`..........`../oo+.../sos.
//                        /sos`  `sss:                `oss+   :sss.
//                      /ooooso: `sos:              `+ooooo+. :sos.
//                     -ssooooss-:sos/              +ssooooso-+sos-
//                     :o+sssssossoooso`            ++ossssosssooos/
//                      `-//:-+soooooos-            ``///::oooooooss`
//                            -/+ssssso`                   /:osssss+
//                              -o+-.`                       /s/-.`
    /**
     * Le constructeur initialise le plateau de jeu a une taille fixe et lance
     * le timer d'événements global tout en effectuant une mesure du temsp pour
     * le calcul du score.
     * @param ma
     */
    public Ville(Maadjo ma) {
        maad = ma;
        int taille = 40;
        argent = 20000; // on commence avec 200 000 adjo
        board = new Board(taille);//Le 40 est à passe en parametre.
        population = 1;
        populationActuelle = 1;
        attractivite = 1;
        travailleur = 1;
        securite = 0;
        batimentImpot = new Batiment[taille * taille];
        travailleurList = new Travailleur[taille * taille];
        industrieList = new Industrie[taille * taille];
        commerceList = new Commerce[taille * taille];
        vecteurInfra = new Vector<Infrastructure>(taille * taille);
        //attention timer: temps en ms
        time = new Timer(5000, actionJeuGlobal); //timer pour les evenement ville
        time.start();
        tempsDebut = System.currentTimeMillis();
        MaxConsommation = 200;
    }

    /**
     * Construction prend en compte un batiment et l'ajoute sur la carte tout
     * en prenant compte de sa taille.
     * @param x positionX
     * @param y positionY
     * @param a batiment à intégrer a ville
     * pré-conditions:
     * x est compris entre 0 et taille
     * y est compris entre 0 et taille
     * a à déjà été initialisé
     * post-conditions:
     */
    public void construction(int x, int y, Infrastructure a) {
        try {
            available.acquire();
            //System.out.println("Je construit un " + a);
            a.ajoutAVille(x, y);

            //on lie le batiment aux cases qu'il occupe
            for (int i = 0; i < a.getLargeur(); i++) {
                for (int j = 0; j < a.getHauteur(); j++) {
                    board.setInfra(x + i, y + j, a);
                }
            }
            vecteurInfra.add(a);
            available.release();

        } catch (Exception e) {
            System.out.println(e);
        }
        if(a.getClass().getName().equals("Model.Construction.Services.Route"))
        {
	        int i = 0;
	        //System.out.println("\n\nJe rentre dans route");
	        while(commerceList[i] != null)
	        {
//		        System.out.println("CommerceList[0] = "+commerceList[0].getPosX()+","+commerceList[0].getPosY());
//		        if(industrieList[i] != null){System.out.println("IndustrieList[0] = "+industrieList[0].getPosX()+","+industrieList[0].getPosY());}
		        Parcourir(commerceList[i]);
		        i++;
	        }
        }
    }

    /**
     * Destruction supprime le batiment et appelle la fonction de destruction
     * du batiment
     * @param x positionX
     * @param y positionY
     * pré-conditions:
     * x est compris entre 0 et taille
     * y est compris entre 0 et taille
     * post-conditions:
     * le batiment situé en (x,y) est supprimé du vecteur et du plateau et
     * exécute sa propre fonction de suppression
     */
    public void destruction(int x, int y) {
        Infrastructure inf = board.getObject(y, x);
        inf.destruction();
        x = inf.getPosX();
        y = inf.getPosY();
        for (int i = x; i <= x + inf.getLargeur(); i++) {
            for (int j = y; j <= y + inf.getHauteur(); j++) {
                getBoard().setInfra(i, j, null);
            }
        }
        vecteurInfra.remove(inf);
    }

    /**
     *_Parcourir correspond à la fonction recursive servant a se deplacer
     * dans l arbre qui a pour racine le Commerce passe en parametre de la
     * la methode pricipale Parcourir.
     * @param r : route r, on va detecter les cases adjacentes a routes.
     * - si c est une route, alors on relance_parcourir sur cette route
     * - si c est une industrie, o, ajoute cette industrie dans la liste
     * des industries liste_ind
     * @param liste_ind : liste d industries etant reliees au commerce.
     *
     * Pre-condition :
     * r est une Route instanciee
     * liste_ind est un tableau instancie
     *
     * Post-Condition :
     * 0 ou plusieurs industries ont etes rajoute dans liste_ind
     */
    private void _Parcourir(Route r, Industrie[] liste_ind) {
        int x = r.getPosX();
        int y = r.getPosY();
        r.set_bool_parcours(true);
        //case au dessus
        if (y > 0 && board.getObject(y - 1, x) != null && (board.getObject(y - 1, x).getClass().getName().equals(industrie_1)
                || board.getObject(y - 1, x).getClass().getName().equals(industrie_2)
                || board.getObject(y - 1, x).getClass().getName().equals(industrie_3)
                || board.getObject(y - 1, x).getClass().getName().equals(industrie_4))) {
            int i = 0;
            while (liste_ind[i] != null) {
                i++;
            }
            liste_ind[i] = (Industrie) board.getObject(y - 1, x);
        }
        //case a droite
        if (x < 39 && board.getObject(y, x + 1) != null && (board.getObject(y, x + 1).getClass().getName().equals(industrie_1)
                || board.getObject(y, x + 1).getClass().getName().equals(industrie_2)
                || board.getObject(y, x + 1).getClass().getName().equals(industrie_3)
                || board.getObject(y, x + 1).getClass().getName().equals(industrie_4))) {
            int i = 0;
            while (liste_ind[i] != null) {
                i++;
            }
            liste_ind[i] = (Industrie) board.getObject(y, x + 1);
        }
        //case en dessous
        if (y < 39 && board.getObject(y + 1, x) != null && (board.getObject(y + 1, x).getClass().getName().equals(industrie_1)
                || board.getObject(y + 1, x).getClass().getName().equals(industrie_2)
                || board.getObject(y + 1, x).getClass().getName().equals(industrie_3)
                || board.getObject(y + 1, x).getClass().getName().equals(industrie_4))) {
            int i = 0;
            while (liste_ind[i] != null) {
                i++;
            }
            liste_ind[i] = (Industrie) board.getObject(y + 1, x);
        }
        //case a gauche
        if (x > 0 && board.getObject(y, x - 1) != null && (board.getObject(y, x - 1).getClass().getName().equals(industrie_1)
                || board.getObject(y, x - 1).getClass().getName().equals(industrie_2)
                || board.getObject(y, x - 1).getClass().getName().equals(industrie_3)
                || board.getObject(y, x - 1).getClass().getName().equals(industrie_4))) {
            int i = 0;
            while (liste_ind[i] != null) {
                i++;
            }
            liste_ind[i] = (Industrie) board.getObject(y, x - 1);
        }


        //case au dessus
        if (y > 0 && board.getObject(y - 1, x) != null
                && board.getObject(y - 1, x).getClass().getName().equals("Model.Construction.Services.Route")) {
            Route ro = (Route) board.getObject(y - 1, x);
            if (ro.get_bool_parcours() == false) {
                _Parcourir(ro, liste_ind);
            }
        }
        //case a droite
        if (x < 39 && board.getObject(y, x + 1) != null
                && board.getObject(y, x + 1).getClass().getName().equals("Model.Construction.Services.Route")) {
            Route ro = (Route) board.getObject(y, x + 1);
            if (ro.get_bool_parcours() == false) {
                _Parcourir(ro, liste_ind);
            }
        }
        //case en dessous
        if (y < 39 && board.getObject(y + 1, x) != null
                && board.getObject(y + 1, x).getClass().getName().equals("Model.Construction.Services.Route")) {
            Route ro = (Route) board.getObject(y + 1, x);
            if (ro.get_bool_parcours() == false) {
                _Parcourir(ro, liste_ind);
            }
        }
        //case a gauche
        if (x > 0 && board.getObject(y, x - 1) != null
                && board.getObject(y, x - 1).getClass().getName().equals("Model.Construction.Services.Route")) {
            Route ro = (Route) board.getObject(y, x - 1);
            if (ro.get_bool_parcours() == false) {
                _Parcourir(ro, liste_ind);
            }
        }
    }

    /**
     *Parcourir : parcours recursivement le plateau de maniere a trouver les
     * industries qui sont reliees a ce commerce par la route.
     * @param com : Commerce dont on souhaite connaitre les indsutries
     * suceptibles de lui fournir les ressources necessaires.
     *
     * pre-condition : com instancie
     * post-condition : com contient une liste des industries reliées a
     * ce commerce
     */
    public void Parcourir(Commerce com) {
        int x = com.getPosX();
        int y = com.getPosY();
        int taille_x = com.getLargeur();
        int taille_y = com.getHauteur();
        int nb_routes = 0;
        Route[] route_adjacentes = new Route[20];
        Infrastructure infra;



        //Parcours des routes au dessus du batiment
        for (int i = 0; i < taille_y; i++) {

            if (y > 0 && board.getObject(y - 1, x + i) != null
                    && board.getObject(y - 1, x + i).getClass().getName().equals("Model.Construction.Services.Route")) {

                route_adjacentes[nb_routes] = (Route) board.getObject(y - 1, i + x);
                nb_routes++;
            }
        }
        //Parcours des routes a droite du batiment
        for (int i = 0; i < taille_x; i++) {
            if ((y + i) < 39 && board.getObject(y + i, x + taille_y) != null
                    && board.getObject(y + i, x + taille_y).getClass().getName().equals("Model.Construction.Services.Route")) {

                route_adjacentes[nb_routes] = (Route) board.getObject(y + i, x + taille_y);
                nb_routes++;
            }
        }
        //Parcours des routes en dessous du batiment
        for (int i = 0; i < taille_y; i++) {
            if ((i + x) < 39 && board.getObject(y + taille_x, i + x) != null
                    && board.getObject(y + taille_x, i + x).getClass().getName().equals("Model.Construction.Services.Route")) {

                route_adjacentes[nb_routes] = (Route) board.getObject(y + taille_x, i + x);
                nb_routes++;
            }
        }
        //Parcours des routes a gauche du batiment
        for (int i = 0; i < taille_x; i++) {
            if ((x - 1) > 0 && (y + i) > 0 && board.getObject(y + i, x - 1) != null
                    && board.getObject(y + i, x - 1).getClass().getName().equals("Model.Construction.Services.Route")) {

                route_adjacentes[nb_routes] = (Route) board.getObject(y + i, x - 1);
                nb_routes++;
            }
        }

        //ici on as les routes qui sont adjacentes au commerce
        //on parcours pour chaque route les chemins pour récupérer les batiments de productions
        int j = 0;
        Industrie[] liste_industrie = new Industrie[160];
        //on stock la chaine de comparaison pour determiner l'industrie qui pourra
        //approvisionner le commerce, par ex : un magasin de textile a besoin
        // d une usine de textile mais pas d une ferme
        if (com.getClass().getName().equals("Model.Construction.Commerces.Epicerie")) {
            industrie_1 = "Model.Construction.Industrie.FermeLocale";
            industrie_2 = "Model.Construction.Industrie.FermeIndustrielle";
            industrie_3 = " ";
            industrie_4 = " ";
        }

        if (com.getClass().getName().equals("Model.Construction.Commerces.MagasinTextile")) {
            industrie_1 = "Model.Construction.Industrie.UsineTextileLocale";
            industrie_2 = "Model.Construction.Industrie.UsineTextileIndustrielle";
            industrie_3 = " ";
            industrie_4 = " ";
        }

        if (com.getClass().getName().equals("Model.Construction.Commerces.Supermarche")) {
            industrie_1 = "Model.Construction.Industrie.UsineTextileLocale";
            industrie_2 = "Model.Construction.Industrie.UsineTextileIndustrielle";
            industrie_3 = "Model.Construction.Industrie.FermeLocale";
            industrie_4 = "Model.Construction.Industrie.FermeIndustrielle";
        }

        while (j < nb_routes) {
            _Parcourir(route_adjacentes[j], liste_industrie);
            j++;
        }

        // liste_industrie contient toute les industrie en contact avec le commerce.

        //on met a null les doublons

        for (int i = 0; i < 160; i++) {
            for (int k = i + 1; k < 160; k++) {
                if (liste_industrie[i] != null
                        && liste_industrie[k] != null
                        && liste_industrie[i].getPosX() == liste_industrie[k].getPosX()
                        && liste_industrie[i].getPosY() == liste_industrie[k].getPosY()) {
                    liste_industrie[k] = null;
                }
            }

       }
      //on met a null les industrie qui sont plus loin que 6 cases
      for(int i = 0 ; i < 160 ; i++)
       {
           if(liste_industrie[i] != null)
            {
                int xi = Math.abs(liste_industrie[i].getPosX()-com.getPosX());
                int yi = Math.abs(liste_industrie[i].getPosY()-com.getPosY());
            if(Math.sqrt(xi*xi + yi*yi) > 10)
                {
                   // System.out.println("dist : "+Math.sqrt(xi*xi + yi*yi));
                liste_industrie[i] = null;
                }

            }
        }

        // on supprime les doublons

        Industrie[] tmp_indus = new Industrie[160];
        int nb_ind = 0;
        for (int i = 0; i < 160; i++) {
            if (liste_industrie[i] != null) {
                tmp_indus[nb_ind] = liste_industrie[i];
                nb_ind++;
            }
        }

        //on rajoute la liste des industrie dans le commerce.
        com.setListeIndustrie(tmp_indus);

        //on met a jour le boolean qui est inclu dans les routes

        for (int k = 0; k < board.getTaille(); k++) {
            for (int l = 0; l < board.getTaille(); l++) {
                if (board.getObject(k, l) != null
                        && board.getObject(k, l).getClass().getName().equals("Model.Construction.Services.Route")) {
                    Route r = (Route) board.getObject(k, l);
                    r.set_bool_parcours(false);
                }
            }
        }
        
        //com.affiche_industrie();
        
    }

    /**
     * Déplacement permet de déplacer un batiment d'un point d'origine à un p
     * oint arrive.
     * @param xOrig
     * @param yOrig
     * @param x
     * @param y
     * pré-conditions:
     * xOrig, yOrig, x, y sont compris entre 0 et taille
     * post-conditions:
     * le batiment est deplace
     *
     * NON IMPLEMENTE
     */
    public void deplacement(int xOrig, int yOrig, int x, int y) { // TODO
        try {
            available.acquire();
            Infrastructure a = board.getObject(xOrig, yOrig);
            a.deplacement();
            board.setInfra(x, y, a);
            board.removeInfra(xOrig, yOrig);
            available.release();
        } catch (Exception e) {
            System.out.println(e.getMessage());
        }
    }
    ActionListener actionJeuGlobal = new ActionListener() {

        @Override
        public void actionPerformed(ActionEvent evt) {
            incomePopulation();
            repartitionPopToTravailleur();
            releverImpot();
            productionIndustrie();
            commerceConsommation();
            //Calcul des quantites de nourriture, textile consomme
            //appel de la fonction
            testFinJeu();
            //System.out.println("consomme Nourriture: " + (nourritureConsomme) + " textile: " + (textileConsomme));
        }
    };


    /*
     * testfinjeu regarde si la consommation totale de nourriture et de textile
     * est supérieur à la valeur Maxconsommation défini dans le constructeur et si
     * on dépasse cette valeur on calcule le temps, note ce temps et on l'envoie
     * à l'objet gérant les fenetres(MAADJO)
     *
     */
    private void testFinJeu() {
        if (textileConsomme >= MaxConsommation && nourritureConsomme >= MaxConsommation) {

            tempsFin = System.currentTimeMillis();

            double temps = tempsFin - tempsDebut;
            double minute = temps / (60 * 1000);
            //si temps < 10: bon, <20 moyen, >20 faible
            //TO DO lancer exception ou autre
            if (minute < 10) {
                maad.FinPartie(" Vous êtes rapide, temps: " + (int)minute+" min");
            } else if (minute < 20) {
                maad.FinPartie(" Peu mieux faire, temps: " + (int)minute+" min");
            } else {
                maad.FinPartie(" Un peu lent, temps: " + (int)minute+" min");
            }
            time.stop();
            //System.out.println("FIN FIN FIN");
        }
    }
    /*
     * relever impot parcours le tableau de batiment et appele pour chaque
     * batiment la fonction payerImpot.
     * pré-conditions:
     * Aucune
     * post-conditions:
     * Impots releves
     */

    private void releverImpot() {
        for (int i = 0; i < batimentImpot.length; i++) {
            if (batimentImpot[i] != null) {
                batimentImpot[i].payerImpot();
                //System.out.println("Un impot paye");
            }
        }
    }
    /*
     * Calcule l'arrive de population en prenant une valeur fixe et en la
     * diminuant en fonction de l'attractivite de la ville.
     * On ajoute cette arrivee à la population totale.
     * On prend  en compte:
     * Si l'hotel de ville est construit (limitation à 150),
     * Si il y a assez de place pour accueillir les gens
     * Si on ne depace pas le max
     * pré-conditions:
     * Aucune
     * post-conditions:
     * Population justement ajouté en fonction des 3 conditions precedentes
     */

    private void incomePopulation() {
        double tmp = incomePopulation * calculAttractivitePourCent();
        if (hotelVilleConstruit) {
            if (populationActuelle + (int) tmp <= population) {
                populationActuelle += (int) tmp;
            } else {
                populationActuelle = population;
            }
        } else {
            if (populationActuelle + (int) tmp <= population && populationActuelle + (int) tmp <= limitePopSansHotel) {
                populationActuelle += (int) tmp;
            } else if (populationActuelle + (int) tmp <= population && populationActuelle + (int) tmp > limitePopSansHotel) {
                if (population > limitePopSansHotel) {
                    populationActuelle = limitePopSansHotel;
                } else {
                    populationActuelle = population;
                }
            } else if (populationActuelle + (int) tmp > population && populationActuelle + (int) tmp <= limitePopSansHotel) {
                populationActuelle = population;
            } else if (populationActuelle + (int) tmp > population && populationActuelle + (int) tmp > limitePopSansHotel) {
                if (population > limitePopSansHotel) {
                    populationActuelle = limitePopSansHotel;
                } else {
                    populationActuelle = population;
                }
            }
        }
    }
    /*
     * Ici on regarde la différence entre la population et le nombre de travailleur,
     * cela nous donne le nombre de travailleur à dépensé dans les industries.
     * Et de la on parcourt et rempli chaque industrie jusqu'a epuisement des travailleurs.
     *
     */

    private void repartitionPopToTravailleur() {
        for (int i = 0; i < travailleurList.length; i++) {
            if (travailleurList[i] != null && travailleur < populationActuelle) {
                //System.out.println(travailleurList[i].getTravailleur()+"/"+travailleurList[i].getTravailleurMax());
                int max = travailleurList[i].getTravailleurMax();
                int cour = travailleurList[i].getTravailleur();
                if (max - cour + travailleur <= populationActuelle) {
                    travailleurList[i].addTravailleur(max - cour);
                } else {
                    travailleurList[i].addTravailleur(populationActuelle - travailleur);
                }
            }
        }
    }
    /*
     * productionIndustrie indique à toute les industries de produire leur bien
     * respectif
     *
     */

    private void productionIndustrie() {
        for (int i = 0; i < industrieList.length; i++) {
            if (industrieList[i] != null) {
                industrieList[i].Produit();
            }
        }
    }
    /*
     * les commerces vont ici aller chercher les biens produits par les usines
     * et les vendres.
     *
     */

    private void commerceConsommation() {
        for (int i = 0; i < commerceList.length; i++) {
            if (commerceList[i] != null) {
                commerceList[i].consommation();
            }
        }
    }
    /*
     * le calcul de l'attractivite repose sur 4 facteurs:
     * la securité: entre 0 et 20%
     * la densite: entre 0 et 40%
     * le chomage: entre 0 et 20%
     * l'attractivite: entre 0 et 20%
     * l'addition de ces trois facteurs indique la pénalité du joueur variant
     * donc entre 0 et 100%.
     */

    private double calculAttractivitePourCent() {
        double securit = calculeSecurite();
        double densite = calculeDensitePopulation();
        double chomage = calculeChomage();
        double attrac = calculeAttractivite();
        //System.out.println("sec "+securit+" dens " +densite+" chom "+chomage+ " attrac "+attrac );
        //System.out.println((attractivite - (securit + densite + chomage +attrac)*attractivite) / attractivite);
        return (attractivite - (securit + densite + chomage + attrac) * attractivite) / attractivite;

    }

    /**
     * La securite est calcule en disant que un poste de police protége 20
     * habitants et donc on regarde le pourentage de la population couverte
     */
    private double calculeSecurite() {
        double tmp = (double) securite * 20 / populationActuelle;
        if (tmp < 0.4) {
            return 0.2;
        } else if (tmp < 0.6) {
            return 0.1;
        } else {
            return 0;
        }
    }

    /**
     * la densite de population est le ratio population / place disponible:
     * une ville trop fortement peuple ou pas assez entraine une penalite
     *
     */
    private double calculeDensitePopulation() {
        double tmp = (double) populationActuelle / population;
        if (tmp < 0.3 || tmp > 0.9) {
            return 0.4;
        } else if (tmp < 0.5 || tmp > 0.8) {
            return 0.2;
        } else {
            return 0;
        }
    }

    /**
     *
     * le taux de chomeur entraine aussi une penalite
     *
     */
    private double calculeChomage() {
        double tmp = (double) (populationActuelle - travailleur) / populationActuelle;
        if (tmp < 0.4) {
            return 0;
        } else if (tmp < 0.6) {
            return 0.1;
        } else {
            return 0.2;
        }
    }

    /**
     * l'attractivite décrite ici est plus ce que l'on appellerais du divertissement
     * et est généré par des batiments attractifs
     * ici un point d'attractivite divertit un habitant
     *
     */
    private double calculeAttractivite() {
        double tmp = (double) attractivite / populationActuelle;
        if (tmp > 1) {
            return 0;
        } else if (tmp > 0.6) {
            return 0.1;
        } else {
            return 0.2;
        }
    }

    /**
     * add remove à volonté !!!!
     *
     * REMARQUE IMPORTANTE
     * tous les add/remove ne font pas de test quand à la possibilite d'effectuer
     * ce qu'il font, en effet nous avons pris en compte ce fait dans les fonctions
     * appelante.
     * de ce fait
     *
     * pré-conditions:
     *  La valeur à ajouter/enlever ne créera pas d'incompatibilité
     * (dépacement de valeur, valeur negative ...)
     *
     * post-conditions:
     * l'incrementation/decrementation est effectue.
     *
     */
    /*
     *Ajoute un travailleur dans les stats de la ville
     *
     * @param num nombre de travailleur
     */
    public void addTravailleur(int num) {
        travailleur += num;
    }

    /**
     * Enleve un travailleur des stats de la ville
     *
     * @param num nombre de travailleur
     *
     *
     */
    public void removeTravailleur(int num) {
        travailleur -= num;
    }

    /**
     *
     * @param num nombre de personne
     */
    public void addPopulation(int num) {
        population += num;
    }

    /**
     *
     * @param num
     */
    public void removePopulation(int num) {
        population -= num;
    }

    /**
     *
     * @param num
     */
    public void addPopulationActuelle(int num) {
        populationActuelle += num;
    }

    /**
     *
     * @param num
     */
    public void removePopulationActuelle(int num) {
        populationActuelle -= num;
    }

    /**
     *
     * @param num
     */
    public void addArgent(int num) {
        argent += num;
    }

    /**
     *
     * @param num
     * @return
     */
    public void removeArgent(int num) {
        argent -= num;
    }

    /**
     *
     * @param cout
     * @return
     */
    public boolean argentEstSuffisant(int cout) {
        return (argent - cout >= 0);
    }

    /**
     *
     * @param num
     */
    public void addAttractivite(int num) {
        attractivite += num;
        //System.out.println("attaractivite "+attractivite);
    }

    /**
     *
     * @param num
     */
    public void removeAttractivite(int num) {
        attractivite -= num;
    }

    /**
     *
     */
    public void addSecurite() {
        securite++;
    }

    /**
     *
     */
    public void removeSecurite() {
        securite--;
    }

    /**
     * Ajoute un batiment à la liste des batiment susceptible de payer des impots
     *
     * @param a
     *
     * pré-conditions:
     * a est initiailse et fonctionnel et est present dans la liste
     *
     * post-conditions:
     * a est ajoute à la liste
     *
     */
    public void addBatimentImpot(Batiment a) {
        int i = 0;
        while (batimentImpot[i] != null) {
            i++;
        }
        batimentImpot[i] = a;
    }
    //TODO verifier ce code dessus et dessous

    /**
     * enleve le batiment a de la liste
     * @param a
     */
    public void removeBatimentImpot(Batiment a) {
        int i = 0;
        while (!(batimentImpot[i] == a) && i < batimentImpot.length) {
            i++;
        }
        batimentImpot[i] = null;
    }

    /**
     * Ajoute un batiment à la liste des batiment susceptible de recevoir
     * des travailleurs
     *
     * @param a
     *
     * pré-conditions:
     * a est initiailse et fonctionnel et est present dans la liste
     *
     * post-conditions:
     * a est ajoute à la liste
     */
    public void addBatimentTravailleur(Travailleur a) {
        int i = 0;
        while (travailleurList[i] != null) {
            i++;
        }
        travailleurList[i] = a;
    }

    /**
     * enleve le batiment a de la liste
     * @param a
     */
    public void removeBatimentTravailleur(Batiment a) {
        int i = 0;
        while (!(travailleurList[i] == a) && i < travailleurList.length) {
            i++;
        }
        travailleurList[i] = null;
    }

    /**
     * Ajoute un batiment à la liste des batiment susceptible de produire des biens
     *
     * @param a
     *
     *  pré-conditions:
     * a est initiailse et fonctionnel et est present dans la liste
     *
     * post-conditions:
     * a est ajoute à la liste
     */
    public void addIndustrieProduction(Industrie a) {
        int i = 0;
        while (industrieList[i] != null) {
            i++;
        }
        industrieList[i] = a;
    }

    /**
     *
     * @param a
     */
    public void removeIndustrieProduction(Industrie a) {
        int i = 0;
        while (!(industrieList[i] == a) && i < industrieList.length) {
            i++;
        }
        industrieList[i] = null;
    }

    /**
     *
     * @param a
     */
    public void addCommerceList(Commerce a) {
        int i = 0;
        while (commerceList[i] != null) {
            i++;
        }
        commerceList[i] = a;
    }

    /**
     *
     * @param a
     */
    public void removeCommerceList(Commerce a) {
        int i = 0;
        while (!(commerceList[i] == a) && i < commerceList.length) {
            i++;
        }
        commerceList[i] = null;
    }

    /**
     *
     * @param a
     */
    public void addNourritureConsomme(int a) {
        nourritureConsomme += a;
    }

    /**
     *
     * @param a
     */
    public void addTextileConsomme(int a) {
        textileConsomme += a;
    }


    /*
     *
     *
     * get set time
     *
     *
     */
    /**
     *
     * @return
     */
    public Vector<Infrastructure> getVecteurInfra() {
        return vecteurInfra;
    }

    /**
     *
     * @return
     */
    public Board getBoard() {
        return board;
    }

    /**
     *
     * @return
     */
    public int getAttractivite() {
        return (int) (calculAttractivitePourCent() * 100);
    }

    /**
     *
     * @return
     */
    public int getArgent() {
        return argent;
    }

    /**
     *
     * @return
     */
    public int getTravailleur() {
        return travailleur;
    }

    /**
     *
     * @return
     */
    public int getPopulation() {
        return population;
    }

    /**
     *
     * @return
     */
    public int getPopulationActuelle() {
        return populationActuelle;
    }

    /**
     *
     * @return
     */
    public int getSecurite() {
        return securite;
    }

    /**
     *
     * @return
     */
    public boolean getHotelVilleConstruit() {
        return hotelVilleConstruit;
    }

    /**
     *
     * @param b
     */
    public void setHotelVilleConstruit(boolean b) {
        hotelVilleConstruit = b;
    }

    public int getNourritureConsomme() {
        return nourritureConsomme;
    }

    public int getTextileConsomme() {
        return textileConsomme;
    }
}
